<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>中俊为 | we harmonyos</title>
    <meta name="generator" content="VuePress 1.9.7">
    <script>
          var _hmt = _hmt || [];
          (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?39485dba914ae63b24732b6a90688f0b";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
          })();
      </script>
    <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials">
    <meta name="description" content="weharmonyos 鸿蒙论坛 鸿蒙注释 开源鸿蒙 鸿蒙源码 openharmony源码 HarmonyOS源码 HarmonyOS HarmonyOS生态 openharmony开发者文档 鸿蒙生态 鸿蒙系统 华为操作系统 鸿蒙研究站 开放原子开源基金会 百万汉字注解鸿蒙 百篇博客分析鸿蒙">
    <meta property="og:url" content="/blog/43.html">
    <meta property="og:site_name" content="中俊为 | we harmonyos">
    <meta property="og:description" content="本篇关键词：、、、 下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf.zip) 通讯机制相关篇为: v41.04 鸿蒙内核源码分析(通讯总览) | 内核跟人一样都喜欢八卦; v42.08 鸿蒙内核源码分析(自旋锁) | 死等丈夫归来的贞洁烈女; v43.05 鸿蒙内核源码分析(互斥锁) | 有你没她 相安无事; v44.0">
    <meta property="og:type" content="article">
    <meta property="og:locale" content="en-US">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:image:alt" content="中俊为 | we harmonyos">
    <meta name="theme-color" content="#46bd87">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    
    <link rel="preload" href="/assets/css/0.styles.087eb7d3.css" as="style"><link rel="preload" href="/assets/js/app.9a8b95d8.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Layout.c1e797d4.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" as="script"><link rel="preload" href="/assets/js/page--45d433e8.560fef87.js" as="script"><link rel="prefetch" href="/assets/js/160.a8046d43.js"><link rel="prefetch" href="/assets/js/161.29f8564f.js"><link rel="prefetch" href="/assets/js/162.249ee491.js"><link rel="prefetch" href="/assets/js/163.c57d1577.js"><link rel="prefetch" href="/assets/js/164.7a788aaa.js"><link rel="prefetch" href="/assets/js/165.c333afb2.js"><link rel="prefetch" href="/assets/js/166.9bcb7cd6.js"><link rel="prefetch" href="/assets/js/layout-Blog.4a9781d1.js"><link rel="prefetch" href="/assets/js/layout-Layout.7e277e0b.js"><link rel="prefetch" href="/assets/js/layout-NotFound.9326b14e.js"><link rel="prefetch" href="/assets/js/layout-Slide.8dd861e4.js"><link rel="prefetch" href="/assets/js/page--00854288.e2bc8e8a.js"><link rel="prefetch" href="/assets/js/page--00f8db0a.b2a35fe6.js"><link rel="prefetch" href="/assets/js/page--03ad6df0.d48f4c19.js"><link rel="prefetch" href="/assets/js/page--04b12ba8.e8add78d.js"><link rel="prefetch" href="/assets/js/page--070d2528.d24cd503.js"><link rel="prefetch" href="/assets/js/page--086560f0.a6be2844.js"><link rel="prefetch" href="/assets/js/page--090ad32d.fc7da3c3.js"><link rel="prefetch" href="/assets/js/page--0c054030.2886024e.js"><link rel="prefetch" href="/assets/js/page--0d9507c8.a27dee03.js"><link rel="prefetch" href="/assets/js/page--10bd3330.b5165172.js"><link rel="prefetch" href="/assets/js/page--1233b0b2.b5caca9c.js"><link rel="prefetch" href="/assets/js/page--13650e88.61330a2b.js"><link rel="prefetch" href="/assets/js/page--14c850b1.d9a40c31.js"><link rel="prefetch" href="/assets/js/page--15752630.25f9c756.js"><link rel="prefetch" href="/assets/js/page--19150570.58df8995.js"><link rel="prefetch" href="/assets/js/page--19ecf128.130d012b.js"><link rel="prefetch" href="/assets/js/page--1c48eaa8.9a689e30.js"><link rel="prefetch" href="/assets/js/page--1d4dfe96.bd551921.js"><link rel="prefetch" href="/assets/js/page--1dccf870.03d7d9cc.js"><link rel="prefetch" href="/assets/js/page--2074d3c8.06bf5706.js"><link rel="prefetch" href="/assets/js/page--22213c96.e703257a.js"><link rel="prefetch" href="/assets/js/page--2284eb70.514124de.js"><link rel="prefetch" href="/assets/js/page--22d0cd48.11ea1522.js"><link rel="prefetch" href="/assets/js/page--252cc6c8.f9acae83.js"><link rel="prefetch" href="/assets/js/page--2624cab0.4535fea2.js"><link rel="prefetch" href="/assets/js/page--269ff8f9.012e8ae6.js"><link rel="prefetch" href="/assets/js/page--26fcb668.35b2da5d.js"><link rel="prefetch" href="/assets/js/page--2958afe8.216913bc.js"><link rel="prefetch" href="/assets/js/page--2adcbdb0.6dcb4c27.js"><link rel="prefetch" href="/assets/js/page--2bb4a968.aac31797.js"><link rel="prefetch" href="/assets/js/page--2d849908.7bb4e817.js"><link rel="prefetch" href="/assets/js/page--2e10a2e8.42bef48d.js"><link rel="prefetch" href="/assets/js/page--2f94b0b0.0c993df5.js"><link rel="prefetch" href="/assets/js/page--2fe09288.77769dcb.js"><link rel="prefetch" href="/assets/js/page--323c8c08.254a5f78.js"><link rel="prefetch" href="/assets/js/page--33348ff0.a5f99eb0.js"><link rel="prefetch" href="/assets/js/page--340c7ba8.2c9570cb.js"><link rel="prefetch" href="/assets/js/page--34988588.8c8d0363.js"><link rel="prefetch" href="/assets/js/page--36687528.67d84e0d.js"><link rel="prefetch" href="/assets/js/page--37d6dfd6.88e9cd42.js"><link rel="prefetch" href="/assets/js/page--37ec82f0.5419c82d.js"><link rel="prefetch" href="/assets/js/page--37f7cf15.65f72e55.js"><link rel="prefetch" href="/assets/js/page--38c46ea8.5d5150f9.js"><link rel="prefetch" href="/assets/js/page--3a945e48.bf9758fb.js"><link rel="prefetch" href="/assets/js/page--3ab2204c.e08d6316.js"><link rel="prefetch" href="/assets/js/page--3b206828.d83e3926.js"><link rel="prefetch" href="/assets/js/page--3ca475f0.49e5acce.js"><link rel="prefetch" href="/assets/js/page--3cf057c8.8364331d.js"><link rel="prefetch" href="/assets/js/page--3f4c5148.587a8360.js"><link rel="prefetch" href="/assets/js/page--40445530.486bb516.js"><link rel="prefetch" href="/assets/js/page--411c40e8.2eedba0e.js"><link rel="prefetch" href="/assets/js/page--41a84ac8.f4a360a3.js"><link rel="prefetch" href="/assets/js/page--4220f8b5.19b4371f.js"><link rel="prefetch" href="/assets/js/page--43783a68.4faf0866.js"><link rel="prefetch" href="/assets/js/page--44fc4830.a160662c.js"><link rel="prefetch" href="/assets/js/page--47a42388.052314b4.js"><link rel="prefetch" href="/assets/js/page--47d07816.66731286.js"><link rel="prefetch" href="/assets/js/page--48302d68.8d6493cf.js"><link rel="prefetch" href="/assets/js/page--49b43b30.e3684736.js"><link rel="prefetch" href="/assets/js/page--4a001d08.47f7ec45.js"><link rel="prefetch" href="/assets/js/page--4c5c1688.b7ec1f32.js"><link rel="prefetch" href="/assets/js/page--4d541a70.ee807705.js"><link rel="prefetch" href="/assets/js/page--4e2c0628.4f7105a4.js"><link rel="prefetch" href="/assets/js/page--4eb81008.725d26fe.js"><link rel="prefetch" href="/assets/js/page--5087ffa8.dac2aae0.js"><link rel="prefetch" href="/assets/js/page--520c0d70.2beedefb.js"><link rel="prefetch" href="/assets/js/page--52e3f928.2645087c.js"><link rel="prefetch" href="/assets/js/page--53cd0b44.96d4a285.js"><link rel="prefetch" href="/assets/js/page--54eb2c5e.27eb702b.js"><link rel="prefetch" href="/assets/js/page--553ff2a8.fba8ee4f.js"><link rel="prefetch" href="/assets/js/page--5686ab01.547b633c.js"><link rel="prefetch" href="/assets/js/page--56c40070.4e35708a.js"><link rel="prefetch" href="/assets/js/page--570fe248.2b301b36.js"><link rel="prefetch" href="/assets/js/page--596bdbc8.c74cd724.js"><link rel="prefetch" href="/assets/js/page--5a63dfb0.bbd49a9b.js"><link rel="prefetch" href="/assets/js/page--5bc7d548.eda26865.js"><link rel="prefetch" href="/assets/js/page--5f1bd2b0.e02cf88d.js"><link rel="prefetch" href="/assets/js/page--5ff3be68.b2b0e76e.js"><link rel="prefetch" href="/assets/js/page--624fb7e8.666fdc84.js"><link rel="prefetch" href="/assets/js/page--63d3c5b0.b587d38f.js"><link rel="prefetch" href="/assets/js/page--68d79a88.86f62e4d.js"><link rel="prefetch" href="/assets/js/page--6c2b97f0.ed46abea.js"><link rel="prefetch" href="/assets/js/page--6cc6a596.b3827451.js"><link rel="prefetch" href="/assets/js/page--6ea7a148.61a9bc10.js"><link rel="prefetch" href="/assets/js/page--70e38af0.eb8ffc53.js"><link rel="prefetch" href="/assets/js/page--7180d470.73a3a20e.js"><link rel="prefetch" href="/assets/js/page--752f83e8.d5c31640.js"><link rel="prefetch" href="/assets/js/page--778b7d68.5e8e5ea9.js"><link rel="prefetch" href="/assets/js/page--7bb76688.53e305e3.js"><link rel="prefetch" href="/assets/js/page--7c59a86a.ecf88c30.js"><link rel="prefetch" href="/assets/js/page--7df35030.cfa388f4.js"><link rel="prefetch" href="/assets/js/page--7e136008.230e9a15.js"><link rel="prefetch" href="/assets/js/page--89935db0.f79f9e25.js"><link rel="prefetch" href="/assets/js/page--96a322f0.412d537f.js"><link rel="prefetch" href="/assets/js/page--9b5b15f0.a5231547.js"><link rel="prefetch" href="/assets/js/page--a3b2e830.f4ba68fa.js"><link rel="prefetch" href="/assets/js/page--a86adb30.ec08486b.js"><link rel="prefetch" href="/assets/js/page--ad22ce30.4872eca4.js"><link rel="prefetch" href="/assets/js/page--b0c2ad70.8637057e.js"><link rel="prefetch" href="/assets/js/page--b57aa070.43215f9e.js"><link rel="prefetch" href="/assets/js/page--ba329370.b5f22d13.js"><link rel="prefetch" href="/assets/js/page--bdd272b0.aff1d1a9.js"><link rel="prefetch" href="/assets/js/page--c28a65b0.978514c4.js"><link rel="prefetch" href="/assets/js/page--c606edca.49d3396e.js"><link rel="prefetch" href="/assets/js/page--c74258b0.f85195bc.js"><link rel="prefetch" href="/assets/js/page--cae237f0.8a976cc1.js"><link rel="prefetch" href="/assets/js/page--cf9a2af0.7ad20ea2.js"><link rel="prefetch" href="/assets/js/page--d4521df0.a0a74934.js"><link rel="prefetch" href="/assets/js/page--d7f1fd30.160f138a.js"><link rel="prefetch" href="/assets/js/page--dca9f030.9127ab28.js"><link rel="prefetch" href="/assets/js/page--e161e330.34876a6f.js"><link rel="prefetch" href="/assets/js/page--e4f35ef4.690d3ccb.js"><link rel="prefetch" href="/assets/js/page--e501c270.8dc088ee.js"><link rel="prefetch" href="/assets/js/page--e9b9b570.b94764ed.js"><link rel="prefetch" href="/assets/js/page--ea4e0a70.94492571.js"><link rel="prefetch" href="/assets/js/page--ee71a870.b9944792.js"><link rel="prefetch" href="/assets/js/page--f21187b0.d00a5788.js"><link rel="prefetch" href="/assets/js/page--f6c97ab0.ecb91d64.js"><link rel="prefetch" href="/assets/js/page--fb816db0.c1f07c37.js"><link rel="prefetch" href="/assets/js/page--fcf2f51e.71000d71.js"><link rel="prefetch" href="/assets/js/page--ff214cf0.aaa8b0fc.js"><link rel="prefetch" href="/assets/js/page-GN.2f20b55f.js"><link rel="prefetch" href="/assets/js/page-GNFrequentlyAskedQuestions.24e61c26.js"><link rel="prefetch" href="/assets/js/page-GNLanguageandOperation.35e22ff2.js"><link rel="prefetch" href="/assets/js/page-GNQuickStartguide.7cd8e521.js"><link rel="prefetch" href="/assets/js/page-GNReference.1d5d0c6c.js"><link rel="prefetch" href="/assets/js/page-GNSimpleBuildExample.2eb0b7eb.js"><link rel="prefetch" href="/assets/js/page-GNStyleGuide.8a407135.js"><link rel="prefetch" href="/assets/js/page-GNU汇编教程.d208e4d7.js"><link rel="prefetch" href="/assets/js/page-GNvimsyntaxplugin.58d1459e.js"><link rel="prefetch" href="/assets/js/page-GN快速入门.b708bb6a.js"><link rel="prefetch" href="/assets/js/page-Home.97282d71.js"><link rel="prefetch" href="/assets/js/page-HowGNhandlescross-compiling.6ca64957.js"><link rel="prefetch" href="/assets/js/page-Introduction.292088e0.js"><link rel="prefetch" href="/assets/js/page-ninja快速入门.92729e64.js"><link rel="prefetch" href="/assets/js/page-《孙子兵法》全文.402792c5.js"><link rel="prefetch" href="/assets/js/page-《论语》全文.85da0da0.js"><link rel="prefetch" href="/assets/js/page-《诗经》全文.99ebeb52.js"><link rel="prefetch" href="/assets/js/page-《道德经》全文.43627e4e.js"><link rel="prefetch" href="/assets/js/page-两个文档.eb8dd1b7.js"><link rel="prefetch" href="/assets/js/page-主流站点覆盖定期同步更新.1ad02178.js"><link rel="prefetch" href="/assets/js/page-手机版电脑版.b5e8dfea.js"><link rel="prefetch" href="/assets/js/page-捐助方式.6ca91d44.js"><link rel="prefetch" href="/assets/js/page-来源LiteOS和LiteOS-A内核图解.8fa16705.js"><link rel="prefetch" href="/assets/js/page-电脑版手机版.67a0b4a4.js"><link rel="prefetch" href="/assets/js/page-编程语言相关书籍.d9adf7cb.js"><link rel="prefetch" href="/assets/js/page-鸿蒙内核源码分析.bbb451c7.js"><link rel="prefetch" href="/assets/js/vendors~flowchart.46b2de48.js"><link rel="prefetch" href="/assets/js/vendors~mermaid.627fb4be.js"><link rel="prefetch" href="/assets/js/vendors~photo-swipe.cbde97f9.js"><link rel="prefetch" href="/assets/js/vendors~reveal.77b21b7e.js">
    <link rel="stylesheet" href="/assets/css/0.styles.087eb7d3.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container has-navbar has-sidebar has-anchor"><header class="navbar"><!----> <div class="content__navbar-start"></div> <button title="Sidebar Button" class="sidebar-button"><span class="icon"></span></button> <a href="/" class="home-link router-link-active"><!----> <!----> <span class="site-name can-hide">中俊为 | we harmonyos</span></a> <!----> <div class="content__navbar-center"></div> <div class="links"><button tabindex="-1" aria-hidden="true" class="color-button"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="skin-icon"><path d="M224 800c0 9.6 3.2 44.8 6.4 54.4 6.4 48-48 76.8-48 76.8s80 41.6 147.2 0 134.4-134.4
        38.4-195.2c-22.4-12.8-41.6-19.2-57.6-19.2C259.2 716.8 227.2 761.6 224 800zM560 675.2l-32
        51.2c-51.2 51.2-83.2 32-83.2 32 25.6 67.2 0 112-12.8 128 25.6 6.4 51.2 9.6 80 9.6 54.4 0
        102.4-9.6 150.4-32l0 0c3.2 0 3.2-3.2 3.2-3.2 22.4-16 12.8-35.2
        6.4-44.8-9.6-12.8-12.8-25.6-12.8-41.6 0-54.4 60.8-99.2 137.6-99.2 6.4 0 12.8 0 22.4
        0 12.8 0 38.4 9.6 48-25.6 0-3.2 0-3.2 3.2-6.4 0-3.2 3.2-6.4 3.2-6.4 6.4-16 6.4-16 6.4-19.2
        9.6-35.2 16-73.6 16-115.2 0-105.6-41.6-198.4-108.8-268.8C704 396.8 560 675.2 560 675.2zM224
        419.2c0-28.8 22.4-51.2 51.2-51.2 28.8 0 51.2 22.4 51.2 51.2 0 28.8-22.4 51.2-51.2 51.2C246.4
        470.4 224 448 224 419.2zM320 284.8c0-22.4 19.2-41.6 41.6-41.6 22.4 0 41.6 19.2 41.6 41.6 0
        22.4-19.2 41.6-41.6 41.6C339.2 326.4 320 307.2 320 284.8zM457.6 208c0-12.8 12.8-25.6 25.6-25.6
        12.8 0 25.6 12.8 25.6 25.6 0 12.8-12.8 25.6-25.6 25.6C470.4 233.6 457.6 220.8 457.6 208zM128
        505.6C128 592 153.6 672 201.6 736c28.8-60.8 112-60.8 124.8-60.8-16-51.2 16-99.2
        16-99.2l316.8-422.4c-48-19.2-99.2-32-150.4-32C297.6 118.4 128 291.2 128 505.6zM764.8
        86.4c-22.4 19.2-390.4 518.4-390.4 518.4-22.4 28.8-12.8 76.8 22.4 99.2l9.6 6.4c35.2 22.4
        80 12.8 99.2-25.6 0 0 6.4-12.8 9.6-19.2 54.4-105.6 275.2-524.8 288-553.6
        6.4-19.2-3.2-32-19.2-32C777.6 76.8 771.2 80 764.8 86.4z"></path></svg> <div class="color-picker-menu" style="display:none;"><div class="theme-options"><ul class="themecolor-select"><label for="themecolor-select">Theme Color:</label> <li><span class="default-theme"></span></li> </ul> <div class="darkmode-toggle"><label for="darkmode-toggle" class="desc">Theme Mode:</label> <div class="darkmode-switch"><div class="item day"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon light-icon"><path d="M512 256a42.667 42.667 0 0 0 42.667-42.667V128a42.667 42.667 0 0 0-85.334 0v85.333A42.667 42.667 0 0 0 512 256zm384 213.333h-85.333a42.667 42.667 0 0 0 0 85.334H896a42.667 42.667 0 0 0 0-85.334zM256 512a42.667 42.667 0 0 0-42.667-42.667H128a42.667 42.667 0 0 0 0 85.334h85.333A42.667 42.667 0 0 0 256 512zm9.387-298.667a42.667 42.667 0 0 0-59.307 62.72l61.44 59.307a42.667 42.667 0 0 0 31.147 11.947 42.667 42.667 0 0 0 30.72-13.227 42.667 42.667 0 0 0 0-60.16zm459.946 133.974a42.667 42.667 0 0 0 29.44-11.947l61.44-59.307a42.667 42.667 0 0 0-57.6-62.72l-61.44 60.587a42.667 42.667 0 0 0 0 60.16 42.667 42.667 0 0 0 28.16 13.227zM512 768a42.667 42.667 0 0 0-42.667 42.667V896a42.667 42.667 0 0 0 85.334 0v-85.333A42.667 42.667 0 0 0 512 768zm244.48-79.36a42.667 42.667 0 0 0-59.307 61.44l61.44 60.587a42.667 42.667 0 0 0 29.44 11.946 42.667 42.667 0 0 0 30.72-12.8 42.667 42.667 0 0 0 0-60.586zm-488.96 0-61.44 59.307a42.667 42.667 0 0 0 0 60.586 42.667 42.667 0 0 0 30.72 12.8 42.667 42.667 0 0 0 28.587-10.666l61.44-59.307a42.667 42.667 0 0 0-59.307-61.44zM512 341.333A170.667 170.667 0 1 0 682.667 512 170.667 170.667 0 0 0 512 341.333z" fill="currentColor"></path></svg></div> <div class="item auto active"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon auto-icon"><path d="M460.864 539.072H564.8L510.592 376l-49.728 163.072zM872 362.368V149.504H659.648L510.528 0l-149.12 149.504H149.12v212.928L0 511.872l149.12 149.504v212.928h212.352l149.12 149.504 149.12-149.504h212.352V661.376l149.12-149.504L872 362.368zM614.464 693.12l-31.616-90.624H438.272l-31.616 90.624h-85.888l144.576-407.68h90.368l144.576 407.68h-85.824zm0 0" fill="currentColor"></path></svg></div> <div class="item night"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon dark-icon"><path d="M935.539 630.402c-11.43-11.432-28.674-14.739-43.531-8.354-46.734 20.103-96.363 30.297-147.508 30.297-99.59 0-193.221-38.784-263.64-109.203-108.637-108.637-139.61-270.022-78.908-411.148a39.497 39.497 0 0 0-51.886-51.887c-52.637 22.64-100.017 54.81-140.826 95.616-85.346 85.346-132.346 198.821-132.346 319.52 0 120.7 47.001 234.172 132.347 319.519S408.063 947.11 528.76 947.11c120.7 0 234.172-47.003 319.52-132.351 40.809-40.81 72.978-88.19 95.616-140.826a39.497 39.497 0 0 0-8.356-43.532z" fill="currentColor"></path></svg></div></div> <!----></div></div></div></button> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
        文档中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
        博客中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
        论坛中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
        手册中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div></nav> <!----> <!----> <!----> <div class="content__navbar-end"></div></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><!----> <!----> <div class="content__sidebar-top"></div> <nav class="sidebar-nav-links"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
      文档中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
      博客中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><!----> <a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
      论坛中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
      手册中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><!----> <a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div> <!----></nav> <!----> <div class="content__sidebar-center"></div> <ul class="sidebar-links"><li><a href="/blog/101.html" class="sidebar-link">总目录</a></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">基础知识 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">进程管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">任务管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内存管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable open"><!----> <span class="title">通讯机制 | 14</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/index/5_ipc.html" class="sidebar-link">本章目录</a></li><li><a href="/blog/41.html" class="sidebar-link">通讯总览</a></li><li><a href="/blog/42.html" class="sidebar-link">自旋锁</a></li><li><a href="/blog/43.html" aria-current="page" class="active sidebar-link">互斥锁</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/blog/44.html" class="sidebar-link">快锁使用</a></li><li><a href="/blog/45.html" class="sidebar-link">快锁实现</a></li><li><a href="/blog/46.html" class="sidebar-link">读写锁</a></li><li><a href="/blog/47.html" class="sidebar-link">信号量</a></li><li><a href="/blog/48.html" class="sidebar-link">事件机制</a></li><li><a href="/blog/49.html" class="sidebar-link">信号生产</a></li><li><a href="/blog/50.html" class="sidebar-link">信号消费</a></li><li><a href="/blog/51.html" class="sidebar-link">消息队列</a></li><li><a href="/blog/52.html" class="sidebar-link">消息封装</a></li><li><a href="/blog/53.html" class="sidebar-link">消息映射</a></li><li><a href="/blog/54.html" class="sidebar-link">共享内存</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">文件系统 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">硬件架构 | 9</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内核汇编 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">编译运行 | 13</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">调测工具 | 4</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">前因后果 | 4</span> <span class="arrow right"></span></p> <!----></section></li></ul> <!----> <div class="content__sidebar-bottom"></div> <!----></aside> <main class="page"><nav class="breadcrumb disable"><!----></nav> <!----> <div class="content__page-top"></div> <div vocab="https://schema.org/" typeof="Article" class="page-title"><h1><!----> <span property="headline"></span></h1> <div class="page-info"><!----> </div> <!----> <hr></div> <div class="anchor-place-holder"><aside id="anchor"><div class="anchor-wrapper"><ul class="anchor-list"><li class="anchor"><a href="/blog/43.html#本篇说清楚互斥锁" class="anchor-link heading3"><div>本篇说清楚互斥锁</div></a></li><li class="anchor"><a href="/blog/43.html#概述" class="anchor-link heading3"><div>概述</div></a></li><li class="anchor"><a href="/blog/43.html#互斥锁长什么样" class="anchor-link heading3"><div>互斥锁长什么样？</div></a></li><li class="anchor"><a href="/blog/43.html#初始化" class="anchor-link heading3"><div>初始化</div></a></li><li class="anchor"><a href="/blog/43.html#三种申请模式" class="anchor-link heading3"><div>三种申请模式</div></a></li><li class="anchor"><a href="/blog/43.html#申请互斥锁主函数-osmuxpendop" class="anchor-link heading3"><div>申请互斥锁主函数 OsMuxPendOp</div></a></li><li class="anchor"><a href="/blog/43.html#释放锁的主体函数-osmuxpostop" class="anchor-link heading3"><div>释放锁的主体函数 OsMuxPostOp</div></a></li><li class="anchor"><a href="/blog/43.html#编程实例" class="anchor-link heading3"><div>编程实例</div></a></li><li class="anchor"><a href="/blog/43.html#结果验证" class="anchor-link heading3"><div>结果验证</div></a></li><li class="anchor"><a href="/blog/43.html#总结" class="anchor-link heading3"><div>总结</div></a></li><li class="anchor"><a href="/blog/43.html#百文说内核-抓住主脉络" class="anchor-link heading3"><div>百文说内核 | 抓住主脉络</div></a></li><li class="anchor"><a href="/blog/43.html#百万注源码-处处扣细节" class="anchor-link heading3"><div>百万注源码 | 处处扣细节</div></a></li><li class="anchor"><a href="/blog/43.html#关注不迷路-代码即人生" class="anchor-link heading3"><div>关注不迷路 | 代码即人生</div></a></li></ul></div></aside></div> <!----> <div class="content__content-top"></div> <div class="theme-default-content content__default"><p>本篇关键词：、、、</p> <p><a href="https://weharmony.gitee.io/blog/43.html" target="_blank" rel="noopener noreferrer"><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/index/43.png" alt=""></a></p> <p><a href="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/pdf/%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90(%E7%99%BE%E7%AF%87%E5%8D%9A%E5%AE%A2%E5%88%86%E6%9E%90.%E6%8C%96%E9%80%8F%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8).zip" target="_blank" rel="noopener noreferrer">下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf</a></p> <p>通讯机制相关篇为:</p> <ul><li><a href="http://weharmonyos.com/blog/41.html" target="_blank" rel="noopener noreferrer">v41.04 鸿蒙内核源码分析(通讯总览) | 内核跟人一样都喜欢八卦</a></li> <li><a href="http://weharmonyos.com/blog/42.html" target="_blank" rel="noopener noreferrer">v42.08 鸿蒙内核源码分析(自旋锁) | 死等丈夫归来的贞洁烈女</a></li> <li><a href="http://weharmonyos.com/blog/43.html" target="_blank" rel="noopener noreferrer">v43.05 鸿蒙内核源码分析(互斥锁) | 有你没她 相安无事</a></li> <li><a href="http://weharmonyos.com/blog/44.html" target="_blank" rel="noopener noreferrer">v44.02 鸿蒙内核源码分析(快锁使用) | 用户态负责快锁逻辑</a></li> <li><a href="http://weharmonyos.com/blog/45.html" target="_blank" rel="noopener noreferrer">v45.02 鸿蒙内核源码分析(快锁实现) | 内核态负责快锁调度</a></li> <li><a href="http://weharmonyos.com/blog/46.html" target="_blank" rel="noopener noreferrer">v46.01 鸿蒙内核源码分析(读写锁) | 内核如何实现多读单写</a></li> <li><a href="http://weharmonyos.com/blog/47.html" target="_blank" rel="noopener noreferrer">v47.05 鸿蒙内核源码分析(信号量) | 谁在解决任务间的同步</a></li> <li><a href="http://weharmonyos.com/blog/48.html" target="_blank" rel="noopener noreferrer">v48.07 鸿蒙内核源码分析(事件机制) | 多对多任务如何同步</a></li> <li><a href="http://weharmonyos.com/blog/49.html" target="_blank" rel="noopener noreferrer">v49.05 鸿蒙内核源码分析(信号生产) | 年过半百 活力十足</a></li> <li><a href="http://weharmonyos.com/blog/50.html" target="_blank" rel="noopener noreferrer">v50.03 鸿蒙内核源码分析(信号消费) | 谁让CPU连续四次换栈运行</a></li> <li><a href="http://weharmonyos.com/blog/51.html" target="_blank" rel="noopener noreferrer">v51.03 鸿蒙内核源码分析(消息队列) | 进程间如何异步传递大数据</a></li> <li><a href="http://weharmonyos.com/blog/52.html" target="_blank" rel="noopener noreferrer">v52.02 鸿蒙内核源码分析(消息封装) | 剖析LiteIpc(上)进程通讯内容</a></li> <li><a href="http://weharmonyos.com/blog/53.html" target="_blank" rel="noopener noreferrer">v53.01 鸿蒙内核源码分析(消息映射) | 剖析LiteIpc(下)进程通讯机制</a></li> <li><a href="http://weharmonyos.com/blog/54.html" target="_blank" rel="noopener noreferrer">v54.01 鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式</a></li></ul> <h3 id="本篇说清楚互斥锁">本篇说清楚互斥锁</h3> <p>内核中哪些地方会用到互斥锁？看图:
<img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/27/MuxInit.png" alt=""></p> <p>图中是内核有关模块对互斥锁初始化，有文件，有内存，用消息队列等等，使用面非常的广。其实在给内核源码加注的过程中，会看到大量的自旋锁和互斥锁，它们的存在有序的保证了内核和应用程序的正常运行。是非常基础和重要的功能。</p> <h3 id="概述"><strong>概述</strong></h3> <p><strong>自旋锁</strong> 和 <strong>互斥锁</strong> 虽都是锁，但解决的问题不同， 自旋锁解决用于CPU核间共享内存的竞争，而互斥锁解决线程(任务)间共享内存的竞争。</p> <p>自旋锁的特点是死守共享资源，拿不到锁，CPU选择忙等(busy waiting)，等待其他CPU释放资源。所以共享代码段不能太复杂，否则容易死锁，休克。</p> <p>互斥锁的特点是拿不到锁往往原任务阻塞，切换到新任务运行。CPU是会一直跑的。这样很容易会想到几个问题:</p> <p>第一：会出现很多任务在等同一把锁的情况出现，因为切换新任务也可能因要同一把锁而被阻塞，CPU又被调去跑新新任务了。这样就会出现一个等锁的链表。</p> <p>第二：持有锁的一方再申请同一把锁时还能成功吗？ 答案是可以的，这种锁叫递归锁，是鸿蒙内核默认方式。</p> <p>第三：当优先级很高的A任务要锁失败，主动让出CPU进入睡眠，而如果持有锁的B任务优先级很低， 迟迟等不到调度不到B任务运行，无法释放锁怎么办？
答案是会临时调整B任务的优先级，调到A一样高，这样B能很快的被调度到，等B释放锁后其优先级又会被打回原形。所以一个任务的优先级会看情况时高时低。</p> <p>第四:B任务释放锁之后要主动唤醒等锁的任务链表，使他们能加入就绪队列，等待被调度。调度算法是一视同仁的，它只看优先级。</p> <p>带着这些问题，进入鸿蒙内核互斥锁的实现代码，本篇代码量较大， 每行代码都一一注解说明。</p> <h3 id="互斥锁长什么样"><strong>互斥锁长什么样？</strong></h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">enum</span> <span class="token punctuation">{</span>
    LOS_MUX_PRIO_NONE <span class="token operator">=</span> <span class="token number">0</span>，  <span class="token comment">//线程的优先级和调度不会受到互斥锁影响，先来后到，普通排队。</span>
    LOS_MUX_PRIO_INHERIT <span class="token operator">=</span> <span class="token number">1</span>， <span class="token comment">//当高优先级的等待低优先级的线程释放锁时，低优先级的线程以高优先级线程的优先级运行。</span>
           <span class="token comment">//当线程解锁互斥量时，线程的优先级自动被将到它原来的优先级</span>
    LOS_MUX_PRIO_PROTECT <span class="token operator">=</span> <span class="token number">2</span> <span class="token comment">//详见:OsMuxPendOp中的注解，详细说明了LOS_MUX_PRIO_PROTECT的含义</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">enum</span> <span class="token punctuation">{</span>
    LOS_MUX_NORMAL <span class="token operator">=</span> <span class="token number">0</span>，  <span class="token comment">//非递归锁 只有[0。1]两个状态，不做任何特殊的错误检，不进行deadlock detection(死锁检测)</span>
    LOS_MUX_RECURSIVE <span class="token operator">=</span> <span class="token number">1</span>， <span class="token comment">//递归锁 允许同一线程在互斥量解锁前对该互斥量进行多次加锁。递归互斥量维护锁的计数，在解锁次数和加锁次数不相同的情况下，不会释放锁，别的线程就无法加锁此互斥量。</span>
    LOS_MUX_ERRORCHECK <span class="token operator">=</span> <span class="token number">2</span>， <span class="token comment">//进行错误检查，如果一个线程企图对一个已经锁住的mutex进行relock或对未加锁的unlock，将返回一个错误。</span>
    LOS_MUX_DEFAULT <span class="token operator">=</span> LOS_MUX_RECURSIVE <span class="token comment">//鸿蒙系统默认使用递归锁</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token punctuation">{</span> <span class="token comment">//互斥锁的属性</span>
    UINT8 protocol<span class="token punctuation">;</span>  <span class="token comment">//协议</span>
    UINT8 prioceiling<span class="token punctuation">;</span> <span class="token comment">//优先级上限</span>
    UINT8 type<span class="token punctuation">;</span>   <span class="token comment">//类型属性</span>
    UINT8 reserved<span class="token punctuation">;</span>  <span class="token comment">//保留字段</span>
<span class="token punctuation">}</span> LosMuxAttr<span class="token punctuation">;</span>

<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">OsMux</span> <span class="token punctuation">{</span> <span class="token comment">//互斥锁结构体</span>
    UINT32 magic<span class="token punctuation">;</span>        <span class="token comment">/**&lt; magic number */</span>  <span class="token comment">//魔法数字</span>
    LosMuxAttr attr<span class="token punctuation">;</span>     <span class="token comment">/**&lt; Mutex attribute */</span> <span class="token comment">//互斥锁属性</span>
    LOS_DL_LIST holdList<span class="token punctuation">;</span> <span class="token comment">/**&lt; The task holding the lock change */</span> <span class="token comment">//当有任务拿到本锁时，通过holdList节点把锁挂到该任务的锁链表上</span>
    LOS_DL_LIST muxList<span class="token punctuation">;</span> <span class="token comment">/**&lt; Mutex linked list */</span> <span class="token comment">//等这个锁的任务链表，上面挂的都是任务，注意和holdList的区别。</span>
    VOID <span class="token operator">*</span>owner<span class="token punctuation">;</span>         <span class="token comment">/**&lt; The current thread that is locking a mutex */</span> <span class="token comment">//当前拥有这把锁的任务</span>
    UINT16 muxCount<span class="token punctuation">;</span>     <span class="token comment">/**&lt; Times of locking a mutex */</span> <span class="token comment">//锁定互斥体的次数，递归锁允许多次</span>
<span class="token punctuation">}</span> LosMux<span class="token punctuation">;</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>这互斥锁长的明显的比自旋锁丰满多啦，还记得自旋锁的样子吗，就一个变量，单薄到令人心疼。</p> <h3 id="初始化"><strong>初始化</strong></h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code>LITE_OS_SEC_TEXT UINT32 <span class="token function">LOS_MuxInit</span><span class="token punctuation">(</span>LosMux <span class="token operator">*</span>mutex， <span class="token keyword">const</span> LosMuxAttr <span class="token operator">*</span>attr<span class="token punctuation">)</span>
<span class="token punctuation">{</span>   <span class="token comment">//...</span>
    <span class="token function">SCHEDULER_LOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>		<span class="token comment">//拿到调度自旋锁</span>
    mutex<span class="token operator">-&gt;</span>muxCount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>			<span class="token comment">//锁定互斥量的次数</span>
    mutex<span class="token operator">-&gt;</span>owner <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>			<span class="token comment">//持有该锁的任务</span>
    <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>muxList<span class="token punctuation">)</span><span class="token punctuation">;</span>	<span class="token comment">//初始化等待该锁的任务链表</span>
    mutex<span class="token operator">-&gt;</span>magic <span class="token operator">=</span> OS_MUX_MAGIC<span class="token punctuation">;</span>	<span class="token comment">//固定标识，互斥锁的魔法数字</span>
    <span class="token function">SCHEDULER_UNLOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>		<span class="token comment">//释放调度自旋锁</span>
    <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>留意mutex-&gt;muxList，这又是一个双向链表， 双向链表是内核最重要的结构体，不仅仅是鸿蒙内核，在linux内核中(list_head)又何尝不是，牢牢的寄生在宿主结构体上。muxList上挂的是未来所有等待这把锁的任务。</p> <h3 id="三种申请模式"><strong>三种申请模式</strong></h3> <p>申请互斥锁有三种模式：无阻塞模式、永久阻塞模式、定时阻塞模式。</p> <p>无阻塞模式：即任务申请互斥锁时，入参timeout等于0。若当前没有任务持有该互斥锁，或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务，则申请成功，否则立即返回申请失败。</p> <p>永久阻塞模式：即任务申请互斥锁时，入参timeout等于0xFFFFFFFF。若当前没有任务持有该互斥锁，则申请成功。否则，任务进入阻塞态，系统切换到就绪任务中优先级最高者继续执行。任务进入阻塞态后，直到有其他任务释放该互斥锁，阻塞任务才会重新得以执行。</p> <p>定时阻塞模式：即任务申请互斥锁时，0&lt;timeout&lt;0xFFFFFFFF。若当前没有任务持有该互斥锁，则申请成功。否则该任务进入阻塞态，系统切换到就绪任务中优先级最高者继续执行。任务进入阻塞态后，超时前如果有其他任务释放该互斥锁，则该任务可成功获取互斥锁继续执行，若超时前未获取到该互斥锁，接口将返回超时错误码。</p> <p>如果有任务阻塞于该互斥锁，则唤醒被阻塞任务中优先级最高的，该任务进入就绪态，并进行任务调度。
如果没有任务阻塞于该互斥锁，则互斥锁释放成功。</p> <h3 id="申请互斥锁主函数-osmuxpendop"><strong>申请互斥锁主函数 OsMuxPendOp</strong></h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//互斥锁的主体函数，由OsMuxlockUnsafe调用，互斥锁模块最重要的几个函数之一</span>
<span class="token comment">//最坏情况就是拿锁失败，让出CPU，变成阻塞任务，等别的任务释放锁后排到自己了接着执行。 </span>
STATIC UINT32 <span class="token function">OsMuxPendOp</span><span class="token punctuation">(</span>LosTaskCB <span class="token operator">*</span>runTask， LosMux <span class="token operator">*</span>mutex， UINT32 timeout<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 ret<span class="token punctuation">;</span>
    LOS_DL_LIST <span class="token operator">*</span>node <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    LosTaskCB <span class="token operator">*</span>owner <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>muxList<span class="token punctuation">.</span>pstPrev <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>muxList<span class="token punctuation">.</span>pstNext <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//列表为空时的处理</span>
        <span class="token comment">/* This is for mutex macro initialization. */</span>
        mutex<span class="token operator">-&gt;</span>muxCount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//锁计数器清0</span>
        mutex<span class="token operator">-&gt;</span>owner <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span><span class="token comment">//锁没有归属任务</span>
        <span class="token function">LOS_ListInit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>muxList<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化锁的任务链表，后续申请这把锁任务都会挂上去</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>muxCount <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//无task用锁时，肯定能拿到锁了.在里面返回</span>
        mutex<span class="token operator">-&gt;</span>muxCount<span class="token operator">++</span><span class="token punctuation">;</span>				<span class="token comment">//互斥锁计数器加1</span>
        mutex<span class="token operator">-&gt;</span>owner <span class="token operator">=</span> <span class="token punctuation">(</span>VOID <span class="token operator">*</span><span class="token punctuation">)</span>runTask<span class="token punctuation">;</span>	<span class="token comment">//当前任务拿到锁</span>
        <span class="token function">LOS_ListTailInsert</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>runTask<span class="token operator">-&gt;</span>lockList， <span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>holdList<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//持有锁的任务改变了，节点挂到当前task的锁链表</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>runTask<span class="token operator">-&gt;</span>priority <span class="token operator">&gt;</span> mutex<span class="token operator">-&gt;</span>attr<span class="token punctuation">.</span>prioceiling<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>attr<span class="token punctuation">.</span>protocol <span class="token operator">==</span> LOS_MUX_PRIO_PROTECT<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//看保护协议的做法是怎样的？</span>
            <span class="token function">LOS_BitmapSet</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>runTask<span class="token operator">-&gt;</span>priBitMap， runTask<span class="token operator">-&gt;</span>priority<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//1.priBitMap是记录任务优先级变化的位图，这里把任务当前的优先级记录在priBitMap</span>
            <span class="token function">OsTaskPriModify</span><span class="token punctuation">(</span>runTask， mutex<span class="token operator">-&gt;</span>attr<span class="token punctuation">.</span>prioceiling<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//2.把高优先级的mutex-&gt;attr.prioceiling设为当前任务的优先级.</span>
        <span class="token punctuation">}</span><span class="token comment">//注意任务优先级有32个， 是0最高，31最低!!!这里等于提高了任务的优先级，目的是让其在下次调度中继续提高被选中的概率，从而快速的释放锁.</span>
        <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
	<span class="token comment">//递归锁muxCount&gt;0 如果是递归锁就要处理两种情况 1.runtask持有锁 2.锁被别的任务拿走了</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>LosTaskCB <span class="token operator">*</span><span class="token punctuation">)</span>mutex<span class="token operator">-&gt;</span>owner <span class="token operator">==</span> runTask<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>attr<span class="token punctuation">.</span>type <span class="token operator">==</span> LOS_MUX_RECURSIVE<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//第一种情况 runtask是锁持有方</span>
        mutex<span class="token operator">-&gt;</span>muxCount<span class="token operator">++</span><span class="token punctuation">;</span>	<span class="token comment">//递归锁计数器加1，递归锁的目的是防止死锁，鸿蒙默认用的就是递归锁(LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE)</span>
        <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>		<span class="token comment">//成功退出</span>
    <span class="token punctuation">}</span>
	<span class="token comment">//到了这里说明锁在别的任务那里，当前任务只能被阻塞了。</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>timeout<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//参数timeout表示等待多久再来拿锁</span>
        <span class="token keyword">return</span> LOS_EINVAL<span class="token punctuation">;</span><span class="token comment">//timeout = 0表示不等了，没拿到锁就返回不纠结，返回错误。见于LOS_MuxTrylock </span>
    <span class="token punctuation">}</span>
	<span class="token comment">//自己要被阻塞，只能申请调度，让出CPU core 让别的任务上</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">OsPreemptableInSched</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//不能申请调度 (不能调度的原因是因为没有持有调度任务自旋锁)</span>
        <span class="token keyword">return</span> LOS_EDEADLK<span class="token punctuation">;</span><span class="token comment">//返回错误，自旋锁被别的CPU core 持有</span>
    <span class="token punctuation">}</span>

    <span class="token function">OsMuxBitmapSet</span><span class="token punctuation">(</span>mutex， runTask， <span class="token punctuation">(</span>LosTaskCB <span class="token operator">*</span><span class="token punctuation">)</span>mutex<span class="token operator">-&gt;</span>owner<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//设置锁位图，尽可能的提高锁持有任务的优先级</span>

    owner <span class="token operator">=</span> <span class="token punctuation">(</span>LosTaskCB <span class="token operator">*</span><span class="token punctuation">)</span>mutex<span class="token operator">-&gt;</span>owner<span class="token punctuation">;</span>	<span class="token comment">//记录持有锁的任务</span>
    runTask<span class="token operator">-&gt;</span>taskMux <span class="token operator">=</span> <span class="token punctuation">(</span>VOID <span class="token operator">*</span><span class="token punctuation">)</span>mutex<span class="token punctuation">;</span>	<span class="token comment">//记下当前任务在等待这把锁</span>
    node <span class="token operator">=</span> <span class="token function">OsMuxPendFindPos</span><span class="token punctuation">(</span>runTask， mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//在等锁链表中找到一个优先级比当前任务更低的任务</span>
    ret <span class="token operator">=</span> <span class="token function">OsTaskWait</span><span class="token punctuation">(</span>node， timeout， TRUE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//task陷入等待状态 TRUE代表需要调度</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> LOS_ERRNO_TSK_TIMEOUT<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//这行代码虽和OsTaskWait挨在一起，但要过很久才会执行到，因为在OsTaskWait中CPU切换了任务上下文</span>
        runTask<span class="token operator">-&gt;</span>taskMux <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span><span class="token comment">// 所以重新回到这里时可能已经超时了</span>
        ret <span class="token operator">=</span> LOS_ETIMEDOUT<span class="token punctuation">;</span><span class="token comment">//返回超时</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>timeout <span class="token operator">!=</span> LOS_WAIT_FOREVER<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//不是永远等待的情况</span>
        <span class="token function">OsMuxBitmapRestore</span><span class="token punctuation">(</span>mutex， runTask， owner<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//恢复锁的位图</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br></div></div><h3 id="释放锁的主体函数-osmuxpostop"><strong>释放锁的主体函数 OsMuxPostOp</strong></h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//是否有其他任务持有互斥锁而处于阻塞状，如果是就要唤醒它，注意唤醒一个任务的操作是由别的任务完成的</span>
<span class="token comment">//OsMuxPostOp只由OsMuxUnlockUnsafe，参数任务归还锁了，自然就会遇到锁要给谁用的问题， 因为很多任务在申请锁，由OsMuxPostOp来回答这个问题</span>
STATIC UINT32 <span class="token function">OsMuxPostOp</span><span class="token punctuation">(</span>LosTaskCB <span class="token operator">*</span>taskCB， LosMux <span class="token operator">*</span>mutex， BOOL <span class="token operator">*</span>needSched<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    LosTaskCB <span class="token operator">*</span>resumedTask <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">LOS_ListEmpty</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>muxList<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//如果互斥锁列表为空</span>
        <span class="token function">LOS_ListDelete</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>holdList<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//把持有互斥锁的节点摘掉</span>
        mutex<span class="token operator">-&gt;</span>owner <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    resumedTask <span class="token operator">=</span> <span class="token function">OS_TCB_FROM_PENDLIST</span><span class="token punctuation">(</span><span class="token function">LOS_DL_LIST_FIRST</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>muxList<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//拿到等待互斥锁链表的第一个任务实体，接下来要唤醒任务</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>mutex<span class="token operator">-&gt;</span>attr<span class="token punctuation">.</span>protocol <span class="token operator">==</span> LOS_MUX_PRIO_INHERIT<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//互斥锁属性协议是继承会怎么操作？</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>resumedTask<span class="token operator">-&gt;</span>priority <span class="token operator">&gt;</span> taskCB<span class="token operator">-&gt;</span>priority<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//拿到锁的任务优先级低于参数任务优先级</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">LOS_HighBitGet</span><span class="token punctuation">(</span>taskCB<span class="token operator">-&gt;</span>priBitMap<span class="token punctuation">)</span> <span class="token operator">!=</span> resumedTask<span class="token operator">-&gt;</span>priority<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//参数任务bitmap中最低的优先级不等于等待锁的任务优先级</span>
                <span class="token function">LOS_BitmapClr</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>taskCB<span class="token operator">-&gt;</span>priBitMap， resumedTask<span class="token operator">-&gt;</span>priority<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//把等待任务锁的任务的优先级记录在参数任务的bitmap中</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>taskCB<span class="token operator">-&gt;</span>priBitMap <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//如果bitmap不等于0说明参数任务至少有任务调度的优先级</span>
            <span class="token function">OsMuxPostOpSub</span><span class="token punctuation">(</span>taskCB， mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    mutex<span class="token operator">-&gt;</span>muxCount <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">//互斥锁数量为1</span>
    mutex<span class="token operator">-&gt;</span>owner <span class="token operator">=</span> <span class="token punctuation">(</span>VOID <span class="token operator">*</span><span class="token punctuation">)</span>resumedTask<span class="token punctuation">;</span><span class="token comment">//互斥锁的持有人换了</span>
    resumedTask<span class="token operator">-&gt;</span>taskMux <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span><span class="token comment">//resumedTask不再等锁了</span>
    <span class="token function">LOS_ListDelete</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>holdList<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//自然要从等锁链表中把自己摘出去</span>
    <span class="token function">LOS_ListTailInsert</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>resumedTask<span class="token operator">-&gt;</span>lockList， <span class="token operator">&amp;</span>mutex<span class="token operator">-&gt;</span>holdList<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//把锁挂到恢复任务的锁链表上，lockList是任务持有的所有锁记录</span>
    <span class="token function">OsTaskWake</span><span class="token punctuation">(</span>resumedTask<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//resumedTask有了锁就唤醒它，因为当初在没有拿到锁时处于了pend状态</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>needSched <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//如果不为空</span>
        <span class="token operator">*</span>needSched <span class="token operator">=</span> TRUE<span class="token punctuation">;</span><span class="token comment">//就走起再次调度流程</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br></div></div><h3 id="编程实例"><strong>编程实例</strong></h3> <p>本实例实现如下流程。</p> <ul><li>任务Example_TaskEntry创建一个互斥锁，锁任务调度，创建两个任务Example_MutexTask1、Example_MutexTask2.Example_MutexTask2优先级高于Example_MutexTask1，解锁任务调度，然后Example_TaskEntry任务休眠300Tick。</li> <li>Example_MutexTask2被调度，以永久阻塞模式申请互斥锁，并成功获取到该互斥锁，然后任务休眠100Tick，Example_MutexTask2挂起，Example_MutexTask1被唤醒。</li> <li>Example_MutexTask1以定时阻塞模式申请互斥锁，等待时间为10Tick，因互斥锁仍被Example_MutexTask2持有，Example_MutexTask1挂起。10Tick超时时间到达后，Example_MutexTask1被唤醒，以永久阻塞模式申请互斥锁，因互斥锁仍被Example_MutexTask2持有，Example_MutexTask1挂起。</li> <li>100Tick休眠时间到达后，Example_MutexTask2被唤醒， 释放互斥锁，唤醒Example_MutexTask1。Example_MutexTask1成功获取到互斥锁后，释放锁。</li> <li>300Tick休眠时间到达后，任务Example_TaskEntry被调度运行，删除互斥锁，删除两个任务。</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">/* 互斥锁句柄id */</span>
UINT32 g_testMux<span class="token punctuation">;</span>
<span class="token comment">/* 任务ID */</span>
UINT32 g_testTaskId01<span class="token punctuation">;</span>
UINT32 g_testTaskId02<span class="token punctuation">;</span>

VOID <span class="token function">Example_MutexTask1</span><span class="token punctuation">(</span>VOID<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 ret<span class="token punctuation">;</span>

    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task1 try to get  mutex， wait 10 ticks.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">/* 申请互斥锁 */</span>
    ret <span class="token operator">=</span> <span class="token function">LOS_MuxPend</span><span class="token punctuation">(</span>g_testMux， <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task1 get mutex g_testMux.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">/* 释放互斥锁 */</span>
        <span class="token function">LOS_MuxPost</span><span class="token punctuation">(</span>g_testMux<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> LOS_ERRNO_MUX_TIMEOUT <span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task1 timeout and try to get mutex， wait forever.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">/* 申请互斥锁 */</span>
            ret <span class="token operator">=</span> <span class="token function">LOS_MuxPend</span><span class="token punctuation">(</span>g_testMux， LOS_WAIT_FOREVER<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task1 wait forever， get mutex g_testMux.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">/* 释放互斥锁 */</span>
                <span class="token function">LOS_MuxPost</span><span class="token punctuation">(</span>g_testMux<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

VOID <span class="token function">Example_MutexTask2</span><span class="token punctuation">(</span>VOID<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task2 try to get  mutex， wait forever.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">/* 申请互斥锁 */</span>
    <span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token function">LOS_MuxPend</span><span class="token punctuation">(</span>g_testMux， LOS_WAIT_FOREVER<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task2 get mutex g_testMux and suspend 100 ticks.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* 任务休眠100Ticks */</span>
    <span class="token function">LOS_TaskDelay</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task2 resumed and post the g_testMux\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">/* 释放互斥锁 */</span>
    <span class="token function">LOS_MuxPost</span><span class="token punctuation">(</span>g_testMux<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

UINT32 <span class="token function">Example_TaskEntry</span><span class="token punctuation">(</span>VOID<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 ret<span class="token punctuation">;</span>
    TSK_INIT_PARAM_S task1<span class="token punctuation">;</span>
    TSK_INIT_PARAM_S task2<span class="token punctuation">;</span>

    <span class="token comment">/* 创建互斥锁 */</span>
    <span class="token function">LOS_MuxCreate</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>g_testMux<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* 锁任务调度 */</span>
    <span class="token function">LOS_TaskLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* 创建任务1 */</span>
    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>task1， <span class="token number">0</span>， <span class="token keyword">sizeof</span><span class="token punctuation">(</span>TSK_INIT_PARAM_S<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    task1<span class="token punctuation">.</span>pfnTaskEntry <span class="token operator">=</span> <span class="token punctuation">(</span>TSK_ENTRY_FUNC<span class="token punctuation">)</span>Example_MutexTask1<span class="token punctuation">;</span>
    task1<span class="token punctuation">.</span>pcName       <span class="token operator">=</span> <span class="token string">&quot;MutexTsk1&quot;</span><span class="token punctuation">;</span>
    task1<span class="token punctuation">.</span>uwStackSize  <span class="token operator">=</span> LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE<span class="token punctuation">;</span>
    task1<span class="token punctuation">.</span>usTaskPrio   <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
    ret <span class="token operator">=</span> <span class="token function">LOS_TaskCreate</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>g_testTaskId01， <span class="token operator">&amp;</span>task1<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task1 create failed.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> LOS_NOK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">/* 创建任务2 */</span>
    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>task2， <span class="token number">0</span>， <span class="token keyword">sizeof</span><span class="token punctuation">(</span>TSK_INIT_PARAM_S<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    task2<span class="token punctuation">.</span>pfnTaskEntry <span class="token operator">=</span> <span class="token punctuation">(</span>TSK_ENTRY_FUNC<span class="token punctuation">)</span>Example_MutexTask2<span class="token punctuation">;</span>
    task2<span class="token punctuation">.</span>pcName       <span class="token operator">=</span> <span class="token string">&quot;MutexTsk2&quot;</span><span class="token punctuation">;</span>
    task2<span class="token punctuation">.</span>uwStackSize  <span class="token operator">=</span> LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE<span class="token punctuation">;</span>
    task2<span class="token punctuation">.</span>usTaskPrio   <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>
    ret <span class="token operator">=</span> <span class="token function">LOS_TaskCreate</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>g_testTaskId02， <span class="token operator">&amp;</span>task2<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task2 create failed.\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> LOS_NOK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">/* 解锁任务调度 */</span>
    <span class="token function">LOS_TaskUnlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">/* 休眠300Ticks */</span>
    <span class="token function">LOS_TaskDelay</span><span class="token punctuation">(</span><span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* 删除互斥锁 */</span>
    <span class="token function">LOS_MuxDelete</span><span class="token punctuation">(</span>g_testMux<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* 删除任务1 */</span>
    ret <span class="token operator">=</span> <span class="token function">LOS_TaskDelete</span><span class="token punctuation">(</span>g_testTaskId01<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task1 delete failed .\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> LOS_NOK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">/* 删除任务2 */</span>
    ret <span class="token operator">=</span> <span class="token function">LOS_TaskDelete</span><span class="token punctuation">(</span>g_testTaskId02<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;task2 delete failed .\n&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> LOS_NOK<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> LOS_OK<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br><span class="line-number">92</span><br><span class="line-number">93</span><br><span class="line-number">94</span><br><span class="line-number">95</span><br><span class="line-number">96</span><br><span class="line-number">97</span><br><span class="line-number">98</span><br><span class="line-number">99</span><br><span class="line-number">100</span><br><span class="line-number">101</span><br><span class="line-number">102</span><br><span class="line-number">103</span><br><span class="line-number">104</span><br><span class="line-number">105</span><br><span class="line-number">106</span><br><span class="line-number">107</span><br><span class="line-number">108</span><br><span class="line-number">109</span><br><span class="line-number">110</span><br></div></div><h3 id="结果验证"><strong>结果验证</strong></h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code>task2 try to get  mutex， wait forever<span class="token punctuation">.</span>
task2 get mutex g_testMux and suspend <span class="token number">100</span> ticks<span class="token punctuation">.</span>
task1 try to get  mutex， wait <span class="token number">10</span> ticks<span class="token punctuation">.</span>
task1 timeout and try to get mutex， wait forever<span class="token punctuation">.</span>
task2 resumed and post the g_testMux
task1 wait forever，get mutex g_testMux<span class="token punctuation">.</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="总结"><strong>总结</strong></h3> <p>1.互斥锁解决的是任务间竞争共享内存的问题.</p> <p>2.申请锁失败的任务会进入睡眠OsTaskWait，内核会比较持有锁的任务和申请锁任务的优先级，把持有锁的任务优先级调到尽可能的高，以便更快的被调度执行，早日释放锁.</p> <p>3.释放锁的任务会在等锁链表中找一个高优先级任务，通过OsTaskWake唤醒它，并向调度算法申请调度.但要注意，调度算法只是按优先级来调度，并不保证调度后的任务一定是要唤醒的任务.</p> <p>4.互斥锁篇关键是看懂 OsMuxPendOp 和 OsMuxPostOp 两个函数。</p> <h3 id="百文说内核-抓住主脉络">百文说内核 | 抓住主脉络</h3> <ul><li>百文相当于摸出内核的肌肉和器官系统，让人开始丰满有立体感，因是直接从注释源码起步，在加注释过程中，每每有心得处就整理,慢慢形成了以下文章。内容立足源码，常以生活场景打比方尽可能多的将内核知识点置入某种场景，具有画面感，容易理解记忆。说别人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念，那没什么意思。更希望让内核变得栩栩如生，倍感亲切。</li> <li>与代码需不断<code>debug</code>一样，文章内容会存在不少错漏之处，请多包涵，但会反复修正，持续更新，<code>v**.xx</code> 代表文章序号和修改的次数，精雕细琢，言简意赅，力求打造精品内容。</li> <li>百文在 &lt; 鸿蒙研究站 | 开源中国 | 博客园 | 51cto | csdn | 知乎 | 掘金 &gt; 站点发布，百篇博客系列目录如下。</li> <li><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/cate.png" alt=""></li></ul> <p>按功能模块:</p> <table><thead><tr><th style="text-align:center;">基础知识</th> <th style="text-align:center;">进程管理</th> <th style="text-align:center;">任务管理</th> <th style="text-align:center;">内存管理</th></tr></thead> <tbody><tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/01.html" target="_blank" rel="noopener noreferrer">双向链表</a><br><a href="http://weharmonyos.com/blog/02.html" target="_blank" rel="noopener noreferrer">内核概念</a><br><a href="http://weharmonyos.com/blog/03.html" target="_blank" rel="noopener noreferrer">源码结构</a><br><a href="http://weharmonyos.com/blog/04.html" target="_blank" rel="noopener noreferrer">地址空间</a><br><a href="http://weharmonyos.com/blog/05.html" target="_blank" rel="noopener noreferrer">计时单位</a><br><a href="http://weharmonyos.com/blog/06.html" target="_blank" rel="noopener noreferrer">优雅的宏</a><br><a href="http://weharmonyos.com/blog/07.html" target="_blank" rel="noopener noreferrer">钩子框架</a><br><a href="http://weharmonyos.com/blog/08.html" target="_blank" rel="noopener noreferrer">位图管理</a><br><a href="http://weharmonyos.com/blog/09.html" target="_blank" rel="noopener noreferrer">POSIX</a><br><a href="http://weharmonyos.com/blog/10.html" target="_blank" rel="noopener noreferrer">main函数</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/11.html" target="_blank" rel="noopener noreferrer">调度故事</a><br><a href="http://weharmonyos.com/blog/12.html" target="_blank" rel="noopener noreferrer">进程控制块</a><br><a href="http://weharmonyos.com/blog/13.html" target="_blank" rel="noopener noreferrer">进程空间</a><br><a href="http://weharmonyos.com/blog/14.html" target="_blank" rel="noopener noreferrer">线性区</a><br><a href="http://weharmonyos.com/blog/15.html" target="_blank" rel="noopener noreferrer">红黑树</a><br><a href="http://weharmonyos.com/blog/16.html" target="_blank" rel="noopener noreferrer">进程管理</a><br><a href="http://weharmonyos.com/blog/17.html" target="_blank" rel="noopener noreferrer">Fork进程</a><br><a href="http://weharmonyos.com/blog/18.html" target="_blank" rel="noopener noreferrer">进程回收</a><br><a href="http://weharmonyos.com/blog/19.html" target="_blank" rel="noopener noreferrer">Shell编辑</a><br><a href="http://weharmonyos.com/blog/20.html" target="_blank" rel="noopener noreferrer">Shell解析</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/21.html" target="_blank" rel="noopener noreferrer">任务控制块</a><br><a href="http://weharmonyos.com/blog/22.html" target="_blank" rel="noopener noreferrer">并发并行</a><br><a href="http://weharmonyos.com/blog/23.html" target="_blank" rel="noopener noreferrer">就绪队列</a><br><a href="http://weharmonyos.com/blog/24.html" target="_blank" rel="noopener noreferrer">调度机制</a><br><a href="http://weharmonyos.com/blog/25.html" target="_blank" rel="noopener noreferrer">任务管理</a><br><a href="http://weharmonyos.com/blog/26.html" target="_blank" rel="noopener noreferrer">用栈方式</a><br><a href="http://weharmonyos.com/blog/27.html" target="_blank" rel="noopener noreferrer">软件定时器</a><br><a href="http://weharmonyos.com/blog/28.html" target="_blank" rel="noopener noreferrer">控制台</a><br><a href="http://weharmonyos.com/blog/29.html" target="_blank" rel="noopener noreferrer">远程登录</a><br><a href="http://weharmonyos.com/blog/30.html" target="_blank" rel="noopener noreferrer">协议栈</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/31.html" target="_blank" rel="noopener noreferrer">内存规则</a><br><a href="http://weharmonyos.com/blog/32.html" target="_blank" rel="noopener noreferrer">物理内存</a><br><a href="http://weharmonyos.com/blog/33.html" target="_blank" rel="noopener noreferrer">内存概念</a><br><a href="http://weharmonyos.com/blog/34.html" target="_blank" rel="noopener noreferrer">虚实映射</a><br><a href="http://weharmonyos.com/blog/35.html" target="_blank" rel="noopener noreferrer">页表管理</a><br><a href="http://weharmonyos.com/blog/36.html" target="_blank" rel="noopener noreferrer">静态分配</a><br><a href="http://weharmonyos.com/blog/37.html" target="_blank" rel="noopener noreferrer">TLFS算法</a><br><a href="http://weharmonyos.com/blog/38.html" target="_blank" rel="noopener noreferrer">内存池管理</a><br><a href="http://weharmonyos.com/blog/39.html" target="_blank" rel="noopener noreferrer">原子操作</a><br><a href="http://weharmonyos.com/blog/40.html" target="_blank" rel="noopener noreferrer">圆整对齐</a><br></td></tr> <tr><td style="text-align:center;">通讯机制</td> <td style="text-align:center;">文件系统</td> <td style="text-align:center;">硬件架构</td> <td style="text-align:center;">内核汇编</td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/41.html" target="_blank" rel="noopener noreferrer">通讯总览</a><br><a href="http://weharmonyos.com/blog/42.html" target="_blank" rel="noopener noreferrer">自旋锁</a><br><a href="http://weharmonyos.com/blog/43.html" target="_blank" rel="noopener noreferrer">互斥锁</a><br><a href="http://weharmonyos.com/blog/44.html" target="_blank" rel="noopener noreferrer">快锁使用</a><br><a href="http://weharmonyos.com/blog/45.html" target="_blank" rel="noopener noreferrer">快锁实现</a><br><a href="http://weharmonyos.com/blog/46.html" target="_blank" rel="noopener noreferrer">读写锁</a><br><a href="http://weharmonyos.com/blog/47.html" target="_blank" rel="noopener noreferrer">信号量</a><br><a href="http://weharmonyos.com/blog/48.html" target="_blank" rel="noopener noreferrer">事件机制</a><br><a href="http://weharmonyos.com/blog/49.html" target="_blank" rel="noopener noreferrer">信号生产</a><br><a href="http://weharmonyos.com/blog/50.html" target="_blank" rel="noopener noreferrer">信号消费</a><br><a href="http://weharmonyos.com/blog/51.html" target="_blank" rel="noopener noreferrer">消息队列</a><br><a href="http://weharmonyos.com/blog/52.html" target="_blank" rel="noopener noreferrer">消息封装</a><br><a href="http://weharmonyos.com/blog/53.html" target="_blank" rel="noopener noreferrer">消息映射</a><br><a href="http://weharmonyos.com/blog/54.html" target="_blank" rel="noopener noreferrer">共享内存</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/55.html" target="_blank" rel="noopener noreferrer">文件概念</a><br><a href="http://weharmonyos.com/blog/56.html" target="_blank" rel="noopener noreferrer">文件故事</a><br><a href="http://weharmonyos.com/blog/57.html" target="_blank" rel="noopener noreferrer">索引节点</a><br><a href="http://weharmonyos.com/blog/58.html" target="_blank" rel="noopener noreferrer">VFS</a><br><a href="http://weharmonyos.com/blog/59.html" target="_blank" rel="noopener noreferrer">文件句柄</a><br><a href="http://weharmonyos.com/blog/60.html" target="_blank" rel="noopener noreferrer">根文件系统</a><br><a href="http://weharmonyos.com/blog/61.html" target="_blank" rel="noopener noreferrer">挂载机制</a><br><a href="http://weharmonyos.com/blog/62.html" target="_blank" rel="noopener noreferrer">管道文件</a><br><a href="http://weharmonyos.com/blog/63.html" target="_blank" rel="noopener noreferrer">文件映射</a><br><a href="http://weharmonyos.com/blog/64.html" target="_blank" rel="noopener noreferrer">写时拷贝</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/65.html" target="_blank" rel="noopener noreferrer">芯片模式</a><br><a href="http://weharmonyos.com/blog/66.html" target="_blank" rel="noopener noreferrer">ARM架构</a><br><a href="http://weharmonyos.com/blog/67.html" target="_blank" rel="noopener noreferrer">指令集</a><br><a href="http://weharmonyos.com/blog/68.html" target="_blank" rel="noopener noreferrer">协处理器</a><br><a href="http://weharmonyos.com/blog/69.html" target="_blank" rel="noopener noreferrer">工作模式</a><br><a href="http://weharmonyos.com/blog/70.html" target="_blank" rel="noopener noreferrer">寄存器</a><br><a href="http://weharmonyos.com/blog/71.html" target="_blank" rel="noopener noreferrer">多核管理</a><br><a href="http://weharmonyos.com/blog/72.html" target="_blank" rel="noopener noreferrer">中断概念</a><br><a href="http://weharmonyos.com/blog/73.html" target="_blank" rel="noopener noreferrer">中断管理</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/74.html" target="_blank" rel="noopener noreferrer">编码方式</a><br><a href="http://weharmonyos.com/blog/75.html" target="_blank" rel="noopener noreferrer">汇编基础</a><br><a href="http://weharmonyos.com/blog/76.html" target="_blank" rel="noopener noreferrer">汇编传参</a><br><a href="http://weharmonyos.com/blog/77.html" target="_blank" rel="noopener noreferrer">链接脚本</a><br><a href="http://weharmonyos.com/blog/78.html" target="_blank" rel="noopener noreferrer">内核启动</a><br><a href="http://weharmonyos.com/blog/79.html" target="_blank" rel="noopener noreferrer">进程切换</a><br><a href="http://weharmonyos.com/blog/80.html" target="_blank" rel="noopener noreferrer">任务切换</a><br><a href="http://weharmonyos.com/blog/81.html" target="_blank" rel="noopener noreferrer">中断切换</a><br><a href="http://weharmonyos.com/blog/82.html" target="_blank" rel="noopener noreferrer">异常接管</a><br><a href="http://weharmonyos.com/blog/83.html" target="_blank" rel="noopener noreferrer">缺页中断</a><br></td></tr> <tr><td style="text-align:center;">编译运行</td> <td style="text-align:center;">调测工具</td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/84.html" target="_blank" rel="noopener noreferrer">编译过程</a><br><a href="http://weharmonyos.com/blog/85.html" target="_blank" rel="noopener noreferrer">编译构建</a><br><a href="http://weharmonyos.com/blog/86.html" target="_blank" rel="noopener noreferrer">GN语法</a><br><a href="http://weharmonyos.com/blog/87.html" target="_blank" rel="noopener noreferrer">忍者无敌</a><br><a href="http://weharmonyos.com/blog/88.html" target="_blank" rel="noopener noreferrer">ELF格式</a><br><a href="http://weharmonyos.com/blog/89.html" target="_blank" rel="noopener noreferrer">ELF解析</a><br><a href="http://weharmonyos.com/blog/90.html" target="_blank" rel="noopener noreferrer">静态链接</a><br><a href="http://weharmonyos.com/blog/91.html" target="_blank" rel="noopener noreferrer">重定位</a><br><a href="http://weharmonyos.com/blog/92.html" target="_blank" rel="noopener noreferrer">动态链接</a><br><a href="http://weharmonyos.com/blog/93.html" target="_blank" rel="noopener noreferrer">进程映像</a><br><a href="http://weharmonyos.com/blog/94.html" target="_blank" rel="noopener noreferrer">应用启动</a><br><a href="http://weharmonyos.com/blog/95.html" target="_blank" rel="noopener noreferrer">系统调用</a><br><a href="http://weharmonyos.com/blog/96.html" target="_blank" rel="noopener noreferrer">VDSO</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/97.html" target="_blank" rel="noopener noreferrer">模块监控</a><br><a href="http://weharmonyos.com/blog/98.html" target="_blank" rel="noopener noreferrer">日志跟踪</a><br><a href="http://weharmonyos.com/blog/99.html" target="_blank" rel="noopener noreferrer">系统安全</a><br><a href="http://weharmonyos.com/blog/100.html" target="_blank" rel="noopener noreferrer">测试用例</a><br></td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr></tbody></table> <h3 id="百万注源码-处处扣细节">百万注源码 | 处处扣细节</h3> <ul><li><p>百万汉字注解内核目的是要看清楚其毛细血管，细胞结构，等于在拿放大镜看内核。内核并不神秘，带着问题去源码中找答案是很容易上瘾的，你会发现很多文章对一些问题的解读是错误的，或者说不深刻难以自圆其说，你会慢慢形成自己新的解读，而新的解读又会碰到新的问题，如此层层递进，滚滚向前，拿着放大镜根本不愿意放手。</p></li> <li><p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">&lt; gitee</a> | <a href="https://github.com/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">github</a> | <a href="https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files" target="_blank" rel="noopener noreferrer">coding</a> | <a href="https://gitcode.net/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">gitcode &gt;</a> 四大码仓推送 | 同步官方源码。</p> <p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer"><img src="https://gitee.com/weharmony/kernel_liteos_a_note/widgets/widget_card.svg?colors=393222,ebdfc1,fffae5,d8ca9f,393222,a28b40" alt=""></a></p></li></ul> <h3 id="关注不迷路-代码即人生">关注不迷路 | 代码即人生</h3> <p><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/so1so.png" alt=""></p> <ul><li>互联网从业十五年，计算机硕士，技术副总裁</li> <li>关注我，持续更新四十年，即聊技术也聊人生</li> <li>交有趣靠谱的人；做难而正确的事</li> <li>不做作，不炒作，只唯真</li> <li>不唯上，不唯书，只唯实</li></ul> <p><a href="http://weharmonyos.com/donate.html" target="_blank" rel="noopener noreferrer"> &gt;&gt; 捐助名单</a></p> <p>据说喜欢 <strong>点赞 + 分享</strong> 的,后来都成了大神。😃</p></div> <!----> <div class="content__content-bottom"></div> <footer class="page-meta"><!----> <!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/blog/42.html" class="prev"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon prev-icon"><path d="M906.783 588.79c-.02 8.499-6.882 15.36-15.38 15.37l-443.7-.01 75.704 191.682c2.52 6.42.482 13.763-5.038 17.91-5.52 4.168-13.138 4.147-18.616-.092L123.228 524.175a15.362 15.362 0 0 1-6-12.165c0-4.782 2.222-9.277 6-12.185L499.753 210.35a15.388 15.388 0 0 1 9.38-3.195c3.236 0 6.502 1.034 9.236 3.103 5.52 4.147 7.578 11.49 5.038 17.91L447.683 419.84l443.72-.01c8.498.01 15.36 6.881 15.36 15.36l.02 153.6z" fill="currentColor"></path></svg>
        自旋锁
      </a></span> <span class="next"><a href="/blog/44.html">
        快锁使用
        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon next-icon"><path d="M906.772 512c0 4.772-2.211 9.267-5.99 12.175L524.257 813.66a15.37 15.37 0 0 1-18.616.092 15.368 15.368 0 0 1-5.038-17.91l75.714-191.672h-443.73c-8.488 0-15.36-6.881-15.36-15.36v-153.6c0-8.489 6.872-15.36 15.36-15.36h443.73l-75.714-191.682a15.358 15.358 0 0 1 5.048-17.91c5.51-4.158 13.128-4.137 18.606.092l376.525 289.485a15.323 15.323 0 0 1 5.99 12.165z" fill="currentColor"></path></svg></a></span></p></div> <!----> <!----> <div class="content__page-bottom"></div></main> <!----></div><div class="global-ui"><!----><!----><div id="pwa-install"><!----> <div id="install-modal-wrapper" style="display:none;"><div class="background"></div> <div class="install-modal"><div class="header"><button aria-label="Close" class="close-button"><svg width="23" height="22" xmlns="http://www.w3.org/2000/svg" class="icon close-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.12.358a1.224 1.224 0 011.729 0l8.92 8.914L20.686.358a1.224 1.224 0 011.73 1.728L13.497 11l8.92 8.913a1.222 1.222 0 11-1.73 1.729l-8.919-8.913-8.92 8.913a1.224 1.224 0 01-1.729-1.729L10.04 11l-8.92-8.914a1.222 1.222 0 010-1.728z" fill="currentColor"></path></svg></button> <div class="logo"><!----> <div class="title"><h1></h1> <p class="desc">This app can be installed on your PC or mobile device.  This will allow this web app to look and behave like any other installed app.  You will find it in your app lists and be able to pin it to your home screen, start menus or task bars.  This installed web app will also be able to safely interact with other apps and your operating system. </p></div></div></div> <div class="content"><div class="highlight"><!----> <!----></div> <div class="description"><h3>Description</h3> <p></p></div></div> <div class="button-wrapper"><button class="install-button">
        Install <span></span></button> <button class="cancel-button">
        Cancel
      </button></div></div></div></div><div tabindex="-1" role="dialog" aria-hidden="true" class="pswp"><div class="pswp__bg"></div> <div class="pswp__scroll-wrap"><div class="pswp__container"><div class="pswp__item"></div> <div class="pswp__item"></div> <div class="pswp__item"></div></div> <div class="pswp__ui pswp__ui--hidden"><div class="pswp__top-bar"><div class="pswp__counter"></div> <button title="Close" aria-label="Close" class="pswp__button pswp__button--close"></button> <button title="Share" aria-label="Share" class="pswp__button pswp__button--share"></button> <button title="Switch to full screen" aria-label="Switch to full screen" class="pswp__button pswp__button--fs"></button> <button title="Zoom in/out" aria-label="Zoom in/out" class="pswp__button pswp__button--zoom"></button> <div class="pswp__preloader"><div class="pswp__preloader__icn"><div class="pswp__preloader__cut"><div class="pswp__preloader__donut"></div></div></div></div></div> <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class="pswp__share-tooltip"></div></div> <button title="Prev (Arrow Left)" aria-label="Prev (Arrow Left)" class="pswp__button pswp__button--arrow--left"></button> <button title="Next (Arrow Right)" aria-label="Next (Arrow Right)" class="pswp__button pswp__button--arrow--right"></button> <div class="pswp__caption"><div class="pswp__caption__center"></div></div></div></div></div></div></div>
    <script src="/assets/js/app.9a8b95d8.js" defer></script><script src="/assets/js/vendors~layout-Layout.c1e797d4.js" defer></script><script src="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" defer></script><script src="/assets/js/page--45d433e8.560fef87.js" defer></script>
  </body>
</html>
